import { utilCombineObj } from "@/assets/utils";
import { utilDeepClone } from "@/assets/utils/deepClone";

export const supEmits: ("emitGetDetailHandle" | "emitSaveAfter")[] = ["emitGetDetailHandle", "emitSaveAfter"];
export const susEmits: ("emitGetListFn" | "emitToOpen")[] = ["emitGetListFn", "emitToOpen"];
export const sudEmits: "emitGetListFn"[] = ["emitGetListFn"];

type IPageAGetListFn = {
  tableRef: Ref<ITableEx | undefined>;
  searchFormRef?: Ref<ISusEx | undefined>;
  isPageToOne?: boolean;
  fnd?: (searchParams: any) => void;
  fn?: () => void;
};
type IPageAToOpenFn1 = {
  fn?: (searchParams: any) => void;
  dioRef: Ref<ISudEx | undefined>;
  row: any;
};

type IPageAToOpenFn3 = {
  fn?: (searchParams: any) => void;
  dioRef: Ref<ISudEx | undefined>;
};
type IPageAToOpenFnAll = IPageAToOpenFn1 | IPageAToOpenFn3;
/**
 * @description:刷新table
 * @常见写法
 * diologForm无search  emitGetListFn: ({ fn }) => pageEmit.emitGetListFn({ tableRef, fn }),
 * diologForm有search  emitGetListFn: ({ fn }) => pageEmit.emitGetListFn({ tableRef, fn ,searchFormRef}),
 * searchForm emitGetListFn: ({ fn }) => pageEmit.emitGetListFn({ tableRef, fn,isPageToOne:true,searchFormRef }),
 * @tableRef 需要刷新的table组件对应的ref值
 * @searchFormRef 刷新table时所需参数来源(search类型的superForm的form)的Ref值
 * @isPageToOne 刷新时是否跳到列表第一页
 * @fn 刷新成功时的回调 里面做了两件事情 1.成功提示 2.取消loading
 * @fnd 刷新前对参数的处理
 */
async function emitGetListFn({ tableRef, searchFormRef, isPageToOne, fn, fnd }: IPageAGetListFn) {
  let searchParams = searchFormRef?.value ? searchFormRef.value.dataed.formRef.form : {};
  // 转化为boolean值 因为tableRef.value!.emitGetListFn第二个参数类型是布尔值或未定义
  let isPageToOneFinal = !!(isPageToOne || searchFormRef?.value);
  if (fnd) fnd(searchParams);
  await tableRef.value!.emitGetListFn(searchParams, isPageToOneFinal);
  if (fn) fn();
}
/**
 * @description 打开弹窗
 * @固定写法
 * 当search时 emitToOpen: () => pageEmit.emitToOpen({ dioRef: diologFormRef })
 * 当table时固定写法 emitToOpen: ({ row }: any) => pageEmit.emitToOpen({ dioRef: diologFormRef, row })
 * @fn 用于打开前对传入弹窗的数据处理
 * @dioRef 要打开的弹窗的ref值
 * @row 打开弹窗传入的数据
 * @类型 type IPageAToOpenFn1 = {fn?: (searchParams: any) => void;dioRef: Ref<ISudEx | undefined>;row: any;};

   type IPageAToOpenFn3 = {fn?: (searchParams: any) => void;dioRef: Ref<ISudEx | undefined>;};
 */
function emitToOpen(obj: IPageAToOpenFnAll) {
  let objed = utilDeepClone(obj);
  if (objed.fn) objed.fn(objed.row);
  obj.dioRef.value!.dataed.methods.showDialogFn(objed.row);
}
/**
 * @description 为了保证单向数据流而产生 在superForm/form/formItem组件内改变传入superForm的参数
 * @固定写法 写法emitChangeProps: (objd: ISuECommonChangePropsEmitArgue) => pageEmit.emitChangeProps(objd, diologFormProps.value),
 * @objd 由propsName: string[]; e: any;组成  propsName用于描述改变哪个参数 e改变为什么值
 * @data 传入superForm组件的props  传入的是非ref
 */
function emitChangeProps(objd: ISuECommonChangePropsEmitArgue, data: ISuP) {
  objd.propsName.map((ite, index) => {
    if (index != objd.propsName.length - 1) {
      // @ts-ignore
      data = data[ite];
    }
  });
  // @ts-ignore
  data[objd.propsName[objd.propsName.length - 1]] = utilCombineObj(data[objd.propsName[objd.propsName.length - 1]], objd.e, true);
}

export const pageEmit = { emitGetListFn, emitToOpen, emitChangeProps };
